import {
    FC, ReactNode, useCallback, useRef, useEffect
} from 'react';
import { initShader } from '@utils/utils';
import styles from './demo2.module.less';

export interface Demo2Props {
    children?: ReactNode;
}

const Demo2: FC<Demo2Props> = () => {
    const canvasRef = useRef(null);

    const main = useCallback(async (canvas: HTMLCanvasElement) => {
        const gl = canvas.getContext('webgl');

        const VERTEX_SHADER_SOURCE = `
            attribute vec4 aPosition;
            attribute float aPointSize;
            void main() {
                gl_Position = aPosition;
                gl_PointSize = aPointSize;
            }
        `;

        const FRAGMENT_SHADER_SOURCE = `
            precision mediump float;
            uniform vec4 uColor;
            void main() {
                gl_FragColor = uColor;
            }
        `;

        const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE);

        const aPosition = gl.getAttribLocation(program, 'aPosition');
        const aPointSize = gl.getAttribLocation(program, 'aPointSize');
        const uColor = gl.getUniformLocation(program, 'uColor');
        gl.uniform4f(uColor, 1.0, 0.0, 0.0, 1.0);

        const points = new Float32Array([
            -0.5, -0.5,
            0.5, -0.5,
            0.0, 0.5
        ]);

        const sizes = new Float32Array([
            10.0,
            20.0,
            30.0
        ]);

        // const buffer = gl.createBuffer();
        // gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        // gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
        // gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
        // gl.enableVertexAttribArray(aPosition);

        // const sizeBuffer = gl.createBuffer();
        // gl.bindBuffer(gl.ARRAY_BUFFER, sizeBuffer);
        // gl.bufferData(gl.ARRAY_BUFFER, sizes, gl.STATIC_DRAW);
        // gl.vertexAttribPointer(aPointSize, 1, gl.FLOAT, false, 0, 0);
        // gl.enableVertexAttribArray(aPointSize);
        // gl.drawArrays(gl.POINTS, 0, 3);

        // 但是上面这么写会形成2块缓冲区对象，通过数据偏移，可以只用一块缓冲区对象达到如上效果

        const pointList = new Float32Array([
            -0.5, -0.5, 10.0,
            0.5, -0.5, 20.0,
            0.0, 0.5, 30.0
        ]);

        const pointListBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, pointListBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, pointList, gl.STATIC_DRAW);

        const elementByte = pointList.BYTES_PER_ELEMENT;
        gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, elementByte * 3, 0);
        gl.enableVertexAttribArray(aPosition);
        gl.vertexAttribPointer(aPointSize, 1, gl.FLOAT, false, elementByte * 3, elementByte * 2);
        gl.enableVertexAttribArray(aPointSize);
        gl.drawArrays(gl.POINTS, 0, 3);
        return () => {
            console.log('remove');
        };
    }, []);

    useEffect(() => {
        let removeEvent = null;
        if (canvasRef.current) {
            removeEvent = main(canvasRef.current);
        }

        return () => {
            if (typeof removeEvent === 'function') {
                removeEvent?.();
            }
        };
    }, [main]);

    return (
        <div className={styles.demo2}>
            <canvas ref={canvasRef} width="600" height="400" />
        </div>
    );
};

export default Demo2;
